/* Quick hack to view a 3D Point Cloud
 * --
 * Chris Baird,, <cjb@brushtail.apana.org.au>
 */

#include <c64.h>

#define HIRES 0xA000
#define SCREEN 0x8C00

typedef unsigned char byte;

const byte pixels[8] = { 128, 64, 32, 16, 8, 4, 2, 1 };
const unsigned int xtab[40] = {
  0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128,
  136, 144, 152, 160, 168, 176, 184, 192, 200, 208, 216, 224, 232, 240,
  248, 256, 264, 272, 280, 288, 296, 304, 312 };


void plot (unsigned short x, unsigned short y)
{
  static unsigned short plot_addr;
  static byte yt;

  if ((x < 320) && (y < 200))
    {
      yt = y >> 3;
      plot_addr = HIRES + (yt << 8) + (yt << 6) + (xtab[x >> 3]) + (y & 7);
      *((char*)plot_addr) = *(char*)plot_addr | pixels[x & 7];
    }
}


/* Stanford Bunny sourced from
 * http://www.cc.gatech.edu/projects/large_models/bunny.html */
const signed short bunnydata[] = {
#include "bunnydata"
  -1,-2,-3
};


void main (void)
{
  static unsigned int i;
  static signed short *p, xi, yi, zi;
  signed short x, y;

  for (i = 0; i < 500; i++) *((int*)SCREEN+i) = 4112;
  for (i = 0; i < 4000; i++) *((int*)HIRES+i) = 0;

  CIA2.pra = 1;
  VIC.addr = 56;
  VIC.ctrl1 = 59;

  p = (signed short*)&bunnydata;
  do
    {
      VIC.bordercolor = (int)p & 15;
      xi = *p++;
      yi = *p++;
      zi = *p++;
      /* Homework: do funky things to the points like rotation.. */
      x = 160 + (signed short)( ((signed long)xi * 220) >> 15);
      y = 120 - (signed short)( ((signed long)yi * 220) >> 15);
      plot (x, y);
    }
  while ((xi != -1) && (yi != -2) && (zi != -3));

  VIC.bordercolor = 0;
}
